import "./pool";

message Deploy {
    queryId: Int as uint64;
    walletA: Address;
    walletB: Address;
}

message DeployOk {
    queryId: Int as uint64;
}

message(0xd53276db) Excesses {
    queryId: Int as uint64;
}

message(0x0f8a7ea5) JettonTransfer {
    query_id: Int as uint64; // arbitrary request number
    amount: Int as coins; // amount of jettons to transfer
    destination: Address; // address of the new owner of the jettons
    response_destination: Address; // address where to send a response with confirmation of a successful transfer and the rest of the incoming message Toncoins.
    custom_payload: Cell?; // optional custom payload
    forward_ton_amount: Int as coins; // the amount of nanotons to be sent to the destination address.
    forward_payload: Slice as remaining; // optional custom data that should be sent to the destination address.
}

message(0x7362d09c) JettonTransferNotification {
    query_id: Int as uint64;
    amount: Int as coins;
    sender: Address;
    forward_payload: Slice as remaining;
}

message(0xb5de5f9e) Withdraw {
    query_id: Int as uint64;
    amountA: Int as coins;
    amountB: Int as coins;
}

contract Router {
    owner: Address;
    walletA: Address?;
    walletB: Address?;

    init(owner: Address) {
        self.owner = owner;
        self.walletA = null;
        self.walletB = null;
    }
    
    receive(msg: Deploy) {
        self.walletA = msg.walletA;
        self.walletB = msg.walletB;
        self.notify(DeployOk{queryId: msg.queryId}.toCell());
    }
    
    receive(msg: Excesses) {
    }
    
    receive(msg: JettonTransferNotification){
        let ctx: Context = context();
        let ctx_sender: Address = ctx.sender;

        // 挂单
        if(ctx_sender == self.walletA) {
            let forward_payload: Slice = msg.forward_payload;
            let payload: Slice = forward_payload.loadRef().beginParse();
            let id: Int = payload.loadUint(32);
            nativeThrowIf(70, id==1); // 会被jetton wallet视为bounce消息
            let price: Int = payload.loadUint(16);
            let data = InternalInit {
                price: price,
                reverse: msg.amount,
            };
            let init: StateInit = initOf Pool(myAddress(), id);
            self.send_init_msg(init, data, ctx.value);
            return;
        }
        // 交换
        if(ctx_sender == self.walletB) {
            let forward_payload: Slice = msg.forward_payload;
            let payload: Slice = forward_payload.loadRef().beginParse();
            let id: Int = payload.loadUint(32);
            let init: StateInit = initOf Pool(myAddress(), id);
            let poolAddress = contractAddress(init);
            let data = Swap {
                query_id: msg.query_id,
                amount: msg.amount,
                from: msg.sender,
            };
            self.send_swap_msg(poolAddress, data, ctx.value);
            return;
        }
        // 不支持的操作
        nativeThrowIf(70, true);
        return;
    }
    
    receive(msg: Payto){
        let init: StateInit = initOf Pool(myAddress(), msg.id);
        let poolAddress = contractAddress(init);
        nativeThrowUnless(71, sender() == poolAddress);
        self.send_simple_jettons(msg.query_id, 0, msg.amount, msg.to, self.walletB!!);
    }

    receive(msg: Withdraw){
        let ctx: Context = context();
        let value = ctx.value / 2;
        if(msg.amountA >= 10_000){
            self.send_simple_jettons(msg.query_id, value, msg.amountA, ctx.sender, self.walletA!!);
        }
        if(msg.amountB >= 10_000_000){
            self.send_simple_jettons(msg.query_id, value, msg.amountB, ctx.sender, self.walletB!!);
        }
        return;
    }
    
    fun send_init_msg(init: StateInit, data: InternalInit, value: Int){
        send(SendParameters{
            to: contractAddress(init),
            body: data.toCell(),
            value: value,
            mode: SendIgnoreErrors,
            code: init.code,
            data: init.data
        });
    }
    
    fun send_swap_msg(pool: Address, data: Swap, value: Int){
        send(SendParameters{
            to: pool,
            value: value,
            bounce: false,
            mode: SendIgnoreErrors,
            body: data.toCell(),
        });
    }
    
    fun send_simple_jettons(query_id: Int, msg_value: Int, jetton_amount: Int, destination: Address, jetton_address: Address) {
        let forward_payload = beginCell().storeUint(0, 1).endCell().beginParse();
        send(SendParameters{
            to: jetton_address,
            value: msg_value,
            bounce: false,
            mode: SendRemainingValue,
            body: JettonTransfer {
                query_id: query_id,
                amount: jetton_amount,
                destination: destination,
                response_destination: myAddress(),
                custom_payload: emptyCell(),
                forward_ton_amount: 0,
                forward_payload: forward_payload,
 
            }.toCell()
        });
    }
}
